#include "imagerecord.h"
#include "ngtable.h"
#include "source/logger.h"
#include <yaml-cpp/yaml.h>

NGTable &NGTable::getInstance()
{
    static NGTable _instance;
    return _instance;
}


NGTable::NGTable(const std::string& configFilePath) {
    loadConfig(configFilePath);
}

QString NGTable::parseNGListToDescription(const std::vector<int>& ngList) {
    std::vector<int> remainingCodes = ngList;
    QString descriptions;

    // Iterate through all combinations and remove matched codes from the remainingCodes
    for (const auto& combination : getCombinations()) {
        bool match = true;
        for (int code : combination.reasons) {
            if (std::find(remainingCodes.begin(), remainingCodes.end(), code) == remainingCodes.end()) {
                match = false;
                break;
            }
        }
        if (match) {
            // Remove matched codes
            for (int code : combination.reasons) {
                remainingCodes.erase(std::remove(remainingCodes.begin(), remainingCodes.end(), code), remainingCodes.end());
            }
            // Append combination description
            if (!descriptions.isEmpty()) {
                descriptions.append("、");
            }
            descriptions.append(QString::fromStdString(combination.description));
        }
    }

    // Append remaining single reasons
    for (int code : remainingCodes) {
        NGReason reason = getNGReason(code);
        if (!descriptions.isEmpty()) {
            descriptions.append("、");
        }
        descriptions.append(QString::fromStdString(reason.reason));
    }

    return descriptions;
}

void NGTable::loadConfig(const std::string& configFilePath) {
    YAML::Node config = YAML::LoadFile(configFilePath);

    for (const auto& reasonNode : config["NGReasons"]) {
        NGReason reason;
        reason.code = reasonNode["code"].as<int>();
        reason.reason = reasonNode["reason"].as<std::string>();
        ngReasons_[reason.code] = reason;
    }

    for (const auto& combinationNode : config["Combinations"]) {
        NGCombination combination;
        combination.code = combinationNode["code"].as<int>();
        for (const auto& reasonCode : combinationNode["reasons"]) {
            combination.reasons.push_back(reasonCode.as<int>());
        }
        combination.description = combinationNode["description"].as<std::string>();
        ngCombinations_[combination.code] = combination;
    }

    LogDebug << "NGTable loaded with " << ngReasons_.size() << " reasons and " << ngCombinations_.size() << " combinations.";
}


NGReason NGTable::getNGReason(int code) const {
    auto it = ngReasons_.find(code);
    if (it != ngReasons_.end()) {
        return it->second;
    }
    return {0, "Unknown"};
}

NGCombination NGTable::getNGCombination(int code) const {
    auto it = ngCombinations_.find(code);
    if (it != ngCombinations_.end()) {
        return it->second;
    }
    return {0, {}, "Unknown"};
}

std::string NGTable::getNGDescription(int code) const {
    auto it = ngCombinations_.find(code);
    if (it != ngCombinations_.end()) {
        return it->second.description;
    }
    auto reasonIt = ngReasons_.find(code);
    if (reasonIt != ngReasons_.end()) {
        return reasonIt->second.reason;
    }
    return "Unknown";
}

std::vector<NGCombination> NGTable::getCombinations() const {
    std::vector<NGCombination> combinations;
    for (const auto& pair : ngCombinations_) {
        combinations.push_back(pair.second);
    }
    return combinations;
}

void NGTable::mergeDefects(NgCard& target, const NgCard& source) const {
    for (int code : source.getDefects()) {
        target.addDefect(code);
    }
}

void testNgTable()
{


    ImageRecord imgRecord;
    // 填充 imgRecord 数据...
    // 示例检测结果，实际检测逻辑根据项目需求实现
    std::vector<int> detectedIssues = {1, 3, 5};

    NgCard ngCard = imgRecord.getNgCard();

    // 记录单个NG原因
    for (int code : detectedIssues)
    {
        ngCard.addDefect(code);
    }

    // 输出单个检测结果
    for (int code : ngCard.getDefects())
    {
        NGReason reason = NGTable::getInstance().getNGReason(code);
        LogDebug << "Detected issue: " << reason.reason;
    }

    // 检查组合NG原因
    for (const auto& combination : NGTable::getInstance().getCombinations())
    {
        bool match = true;
        for (int code : combination.reasons)
        {
            if (std::find(detectedIssues.begin(), detectedIssues.end(), code) == detectedIssues.end())
            {
                match = false;
                break;
            }
        }
        if (match)
        {
            LogDebug << "Detected combined issue: " << combination.description;
        }
    }

    // 输出所有检测结果
    LogDebug << "Final detected issues: " << ngCard.getDefects().size();
}
